package com.example.mq.mqserver.core;

import com.fasterxml.jackson.core.JsonProcessingException;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;


/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ws
 * Date: 2023-09-30
 * Time: 14:36
 */
/*
* 这个类表示一个交换机
 */

@Data
public class Exchange {
    // 使用 name 作为交换机的唯一标志符
    private String name;
    // 交换机类，DIRECT，FANOUT，TOPIC
    // 默认是 DIRECT （直接交换机）
    private ExchangeType type = ExchangeType.DIRECT;
    // 表示该交换机是否要持久化（是否要存储到硬盘），true 表示要持久化，false 表示不需要
    private  boolean durable = false;
    // 如果当前交换机没人使用，就会自动被删除
    // RabbitMQ 有该功能，自己实现该扩展功能
    private boolean autoDelete = false;
    // argument 表示的是创建交换机的一些额外的参数选项（扩展功能）
    // 通过选项开启不同的功能
    // 为了把 arguments 存到数据库中，需要把 Map 转成 json 格式的字符串
    private Map<String, Object> arguments = new HashMap<>();

    /*
     * 这一组便于数据库使用
     * 方便转换为字符串，便于存储于数据库中
     */
    public String getArguments() {
        // 把当前的 arguments 参数，从 Map 转换成 String （json）
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            return objectMapper.writeValueAsString(arguments);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        // 如果代码真的异常了，返回一个空的 json 字符串
        return "{}";
    }

    /*
     *
     * 把参数从数据库中读取后，构造 Exchange对象，自动调用
     */
    public void setArguments(String argumentsJson) {
        // 把参数中的 argumentsJson 按照 Json 格式解析
        ObjectMapper objectMapper = new ObjectMapper();
        // 第二个参数，用来描述当前 json 字符串，要转成的 java对象 是什么类型
        // 简单类型直接使用的对应类型的类对象
        // 如果是集合类这样的复杂类型马，可以使用 TypeReference 匿名内部类对象，来描述复杂的具体信息（通过泛型参数来描述）
        try {
            this.arguments = objectMapper.readValue(argumentsJson, new TypeReference<HashMap<String, Object>>() {});
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    public void setArguments(Map<String, Object> arguments) {
        this.arguments = arguments;
    }

    /*
     * 这一组针对 Java 内部测试使用
     */
    public  Object getArguments(String key) {
        return arguments.get(key);
    }
    public void setArguments(String key, Object value) {
        arguments.put(key, value);
    }
}
